import 'dart:io';
import 'dart:ui';

import 'package:croppy/croppy.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/Util/FileUtils.dart';
import 'package:flutter_yfree/YFree.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
import 'package:wechat_camera_picker/wechat_camera_picker.dart';

class AssetUtils {
  AssetUtils._();

  static Future<List<AssetEntity>?> selectAssets({
    int maxAssets = 1,
    RequestType requestType = RequestType.common,
    SpecialPickerType? specialPickerType,
    int imageMaxSize = 10, //单位：M
    int videoMaxSize = 100, //单位：M
  }) async {
    return await AssetPicker.pickAssets(
      yPages.first.context,
      pickerConfig: AssetPickerConfig(
        themeColor: YConfig.themeColor,
        maxAssets: maxAssets,
        requestType: requestType,
        specialPickerType: specialPickerType,
        specialItemPosition: SpecialItemPosition.prepend,
        pathNameBuilder: (path) {
          switch (path.name.toLowerCase()) {
            case "recent":
            case "recents":
              return "最近项目";
            case "camera":
              return "相机";
            case "screenshots":
              return "截屏";
            case "pictures":
              return "相册";
            case "weixin":
              return "微信";
            case "favorites":
              return "收藏";
            default:
              return path.name;
          }
        },
        selectPredicate: (context, asset, isSelected) async {
          double fileSizeMB = ((await asset.file)!).lengthSync() / 1024.0 / 1024.0;
          switch (asset.type) {
            case AssetType.image:
              if (fileSizeMB > imageMaxSize) {
                yToast("图片不能超过${imageMaxSize}M");
                return false;
              }
              return true;
            case AssetType.video:
              if (fileSizeMB > videoMaxSize) {
                yToast("视频不能超过${videoMaxSize}M");
                return false;
              }
              return true;
            default:
              return true;
          }
        },
        specialItemBuilder: (BuildContext context, AssetPathEntity? path, int length) {
          // if (path?.isAll != true) return null;
          return InkWell(
            child: Icon(Icons.camera_alt_rounded, size: 42),
            onTap: () async {
              final result = await pickFromCamera(requestType: requestType);
              if (result == null) return;
              final AssetPicker<AssetEntity, AssetPathEntity> picker = context.findAncestorWidgetOfExactType()!;
              final DefaultAssetPickerBuilderDelegate builder = picker.builder as DefaultAssetPickerBuilderDelegate;
              final DefaultAssetPickerProvider p = builder.provider;
              await p.switchPath(PathWrapper<AssetPathEntity>(path: await p.currentPath!.path.obtainForNewProperties()));
              p.selectAsset(result);
            },
          );
        },
      ),
    );
  }

  static Future<AssetEntity?> pickFromCamera({
    RequestType requestType = RequestType.common,
  }) async {
    return CameraPicker.pickFromCamera(
      yPages.first.context,
      pickerConfig: CameraPickerConfig(
        enableRecording: requestType != RequestType.image,
        maximumRecordingDuration: Duration(seconds: 30),
        theme: CameraPicker.themeData(YConfig.themeColor),
      ),
    );
  }

  static Future<File?> cropImage({
    required BuildContext context,
    required String path,
    List<CropAspectRatio?>? allowedAspectRatios,
  }) async {
    final result_croppy = await showMaterialImageCropper(
      context,
      imageProvider: FileImage((File(path))),
      allowedAspectRatios: allowedAspectRatios ?? [CropAspectRatio(width: 1, height: 1)],
    );
    if (result_croppy == null) return null;
    var file = File("${await FileUtils.getDir(FileDir.crop_image)}${DateTime.now().microsecondsSinceEpoch}_${FileUtils.getFileName(path)}");
    await file.writeAsBytes((await result_croppy.uiImage.toByteData(format: ImageByteFormat.png))!.buffer.asUint8List());
    return file;
  }
}
